package com.example.redistest.redislocktest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * \* @author: wky
 * \* Date: 2023-04-20
 * \* Time: 14:23
 * \* To change this template use File | Settings | File Templates.
 * \* Description:CommonLockResourceServiceImpl
 * \
 */
@Service
@Transactional
public class CommonLockResourceServiceImpl implements CommonLockResourceService {

    @Autowired
    RedisTemplate redisTemplate;

    private final long ttlTimeout = 60L;

    @Override
    public boolean getLock(String resourceKeyPrefix, int resourceId, int userId) {
        String lock = resourceKeyPrefix + resourceId;
        String keyStr = "" + userId;
        //如果该userId已经有该项目的锁，锁续期
        if(keyStr.equals(redisTemplate.opsForValue().get(lock.intern()))){
            //锁的可重入
            long ttl = redisTemplate.getExpire(lock);
            //续期时间，自己定
            redisTemplate.expire(lock.intern(),ttl+ttlTimeout, TimeUnit.SECONDS);
            return true;
        }
        //枷锁
        boolean isLock = redisTemplate.opsForValue().setIfAbsent(lock.intern(),userId+"",ttlTimeout,TimeUnit.SECONDS);
        return isLock;
    }

    @Override
    public boolean unLock(String resourceKeyPrefix, int resourceId, int userId) {
        String lock = resourceKeyPrefix + resourceId;
        if((userId+"").equals(redisTemplate.opsForValue().get(lock.intern()))) {
            redisTemplate.delete(lock.intern());
            return true;
        }
        return false;
    }

    @Override
    public boolean resetLock(String resourceKeyPrefix, int resourceId, int userId) {
        String lock = resourceKeyPrefix + resourceId;
        //如果该userId已经有该项目的锁，锁续期
        if((""+userId).equals(redisTemplate.opsForValue().get(lock.intern()))){
            long ttl = redisTemplate.getExpire(lock);
            redisTemplate.expire(lock.intern(),ttl+ttlTimeout,TimeUnit.SECONDS);
            return true;
        }
        return false;
    }
}